package LearnAlgorithm.g_数学问题;

import java.util.stream.IntStream;

/**
 * @version: 1.0
 * @Author: wuqiu
 * @date: 2023-07-17 19:49
 * @description: LeetcodeLearnAlgorithm -> LearnAlgorithm.g_数学问题
 */
/**
 * 0-9999这一万个数按顺序摆放的话，里面会出现多少次字符7
 * 0000
 * 0001
 * ....
 * 9999
 * 可以通过人工推到规律的出：
 * 一共一万行，第一列10个数字等概率出现，7的个数为总数的十分之一，即1000，
 * 同理第二列中的7是1000个，
 * 第三列、第四列分别为1000个，
 * 总数为4000个
 * @return
 */
public class j字符7出现次数 {
    public static void main(String[] args) {
        j字符7出现次数 test = new j字符7出现次数();
        System.out.println(test.countOfSevenIn9999());
        int i = test.countMySelf(20);
        System.out.println(i);
    }

    /**
     * 使用了java的api
     * 流处理的api
     * @return
     */
    public int countOfSevenIn9999() {
        int count = 0;
        for (int i = 0; i < 10000; i++) {
            String s = "" + i;
            IntStream intStream = s.chars().filter(c -> c == '7').map(c -> 1);
            count += intStream.count();
        }
        return count;
    }

    /**
     * 不人工推导规律
     * 不适用API
     * 那就自己写呗
     * 这个方法用来计算1到N之间所有整数中1出现的次数
     * @param N
     * @return
     */
    public int countMySelf(int N) {
        if (N >= 1 && N <= 9) { //递归终止条件
            return 1;
        }
        if (N < 1) {            //递归终止条件
            return 0;
        }
        //计数器
        int count = 0;
        //分离高位和剩余
        int high = 0;
        int other = 0;
        int digitNum = 0;//位数;digitNum最后的生成结果和N的位数少1
        int temp = N;
        while (temp / 10 != 0) {
            digitNum++;
            temp /= 10;
        }
        high = N / (int)Math.pow(10,digitNum);//获得最高位数字
        other = N - high * (int)Math.pow(10,digitNum);//获得其他位的所有数字
        if (high > 1) {
            /*
            如果最高位比1大，
            假如是2且digitNum=3
            则代表包含了2000，那么被包含的数种肯定有1000
            那么也就至少有1000个1可以被添加到count中
             */
            count += (int)Math.pow(10,digitNum);
        } else {//否则最高位只能为1
            //最高位为1，低位数值+1就是高位为1的数字个数，先把这个部分加起来
            count += other + 1;
            // count += other + 0;
        }
        count += high * digitNum * (int)Math.pow(10,digitNum - 1);
        count += countMySelf(other);
        return count;
    }
}
